#include "Player.h"
#include "CharacterController.h"
#include "CustomCharacterController.h"

#include "InputsManager.h"

#include "SpriteHelperLoader.h"
#include "AnimController.h"
#include "CustomAnimController.h"

void Player::init( CCLayer* layer, b2World* world )
{
	CCPoint p;
	p.x = 200.0f;
	p.y = 200.0f;

	// graphics
/*
	SpriteHelperLoader sh("mario_test.pshs");


	std::vector<std::string> animFrames;

	animFrames.push_back("mario_idle");
	animFrames.push_back("mario_jump");
	animFrames.push_back("mario_sprint_jump");
	animFrames.push_back("mario_air_down");
	animFrames.push_back("mario_break");

	//animFrames.push_back("mario_idle");
    animFrames.push_back("mario_walk1");
    animFrames.push_back("mario_walk2");

    animFrames.push_back("mario_sprint1");
    animFrames.push_back("mario_sprint2");
    animFrames.push_back("mario_sprint3");
    
    CCAction* animAction;

	sprite = sh.animSpriteWithUniqueName(animFrames,
                                 ccp(150,200),
                                 NULL,
                                 0.1f,
                                 0, //number of repeats - if its 0 the animation will run forever or until you stop it
                                 &animAction);

	layer->addChild(sprite);
	sprite->setPosition( CCPointMake( p.x, p.y) );
	
	// ANIMATION

	animFrames.clear();
    animFrames.push_back("mario_idle");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_IDLE] = animAction;
	animAction->retain();
	
	animFrames.clear();
    animFrames.push_back("mario_jump");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_JUMP] = animAction;
	animAction->retain();

	animFrames.clear();
    animFrames.push_back("mario_sprint_jump");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_SPRINT_JUMP] = animAction;
	animAction->retain();

	animFrames.clear();
    animFrames.push_back("mario_air_down");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_AIR_DOWN] = animAction;
	animAction->retain();

	animFrames.clear();
    animFrames.push_back("mario_break");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_BREAK] = animAction;
	animAction->retain();

	animFrames.clear();
    animFrames.push_back("mario_idle");
    animFrames.push_back("mario_walk1");
    animFrames.push_back("mario_walk2");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_WALK] = animAction;
	animAction->retain();

	animFrames.clear();
    animFrames.push_back("mario_sprint1");
    animFrames.push_back("mario_sprint2");
    animFrames.push_back("mario_sprint3");
	animAction = sh.actionForFrames( animFrames, 0.1f );
	mAnimList[ANIM_SPRINT] = animAction;
	animAction->retain();
	
	sprite->runAction( mAnimList[ANIM_IDLE] );
	anim_act = ANIM_IDLE;
*/
    
       
	// physics


	// Define the dynamic body.
	//Set up a 1m squared box in the physics world
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
	//bodyDef.userData = sprite;
	bodyDef.fixedRotation = true;
	b2Body *body = world->CreateBody(&bodyDef);
	
	// Define another box shape for our dynamic body.
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box
	
	b2CircleShape dCircle;
	dCircle.m_radius = .5f;

	// Define the dynamic body fixture.
	b2FixtureDef fixtureDef;
	fixtureDef.shape = &dCircle;	
	fixtureDef.density = 1.0f;
	fixtureDef.friction = 0.0f;
	body->CreateFixture(&fixtureDef);


	m_body = body;

	// debug

	// add a label shows "Hello World"
	// create and initialize a label
	CCLabelTTF* _Debug = CCLabelTTF::labelWithString("Debug", "Thonburi", 34);
	// ask director the window size
	CCSize size = CCDirector::sharedDirector()->getWinSize();
	// position the label on the center of the screen
	_Debug->setPosition( ccp(size.width / 2, size.height - 50) );

	// add the label as a child to this layer
	layer->addChild(_Debug, 1);

	Debug = _Debug;

    
    // character controller
    
    m_characterController = new MeatBoyController(m_body);
    
    // graphics
    
    //m_animController = new MarioAnimController( (BasicCharacterController*)m_characterController );

	m_animController = new GenericAnimController( (BasicCharacterController*)m_characterController, "soniccd.pshs", "soniccd" );
    
    sprite = m_animController->getSprite();
    
    layer->addChild(sprite);
	sprite->setPosition( CCPointMake( p.x, p.y) );
}

Player::~Player()
{
    delete m_characterController;
    delete m_animController;
}

void Player::draw( CCPoint Offset )
{
	// debug
	b2Fixture* tmp = m_body->GetFixtureList();
	while( tmp )
	{
		if( tmp->GetType() == b2Shape::e_circle )
		{
			ccDrawCircle( CCPoint( tmp->GetAABB().GetCenter().x /**PTM_RATIO*/  , tmp->GetAABB().GetCenter().y /**PTM_RATIO*/ ), tmp->GetAABB().GetExtents().x /**PTM_RATIO*/, 0.0f, 20, false );
		}
		else
		{
			ccDrawLine( CCPoint( (tmp->GetAABB().lowerBound.x  *PTM_RATIO ) - Offset.x , (tmp->GetAABB().lowerBound.y *PTM_RATIO )  - Offset.y) ,
						CCPoint( (tmp->GetAABB().upperBound.x  *PTM_RATIO ) - Offset.x , (tmp->GetAABB().lowerBound.y *PTM_RATIO )  - Offset.y)  );

			ccDrawLine( CCPoint( (tmp->GetAABB().upperBound.x  *PTM_RATIO ) - Offset.x  , (tmp->GetAABB().lowerBound.y *PTM_RATIO )  - Offset.y)  ,
						CCPoint( (tmp->GetAABB().upperBound.x  *PTM_RATIO  ) - Offset.x , (tmp->GetAABB().upperBound.y *PTM_RATIO )  - Offset.y)   );

			ccDrawLine( CCPoint( (tmp->GetAABB().upperBound.x  *PTM_RATIO ) - Offset.x  , (tmp->GetAABB().upperBound.y *PTM_RATIO )  - Offset.y) ,
						CCPoint( (tmp->GetAABB().lowerBound.x  *PTM_RATIO ) - Offset.x  , (tmp->GetAABB().upperBound.y *PTM_RATIO )  - Offset.y)   );

			ccDrawLine( CCPoint( (tmp->GetAABB().lowerBound.x  *PTM_RATIO ) - Offset.x  , (tmp->GetAABB().upperBound.y *PTM_RATIO )  - Offset.y)  ,
						CCPoint(( tmp->GetAABB().lowerBound.x  *PTM_RATIO ) - Offset.x  , (tmp->GetAABB().lowerBound.y *PTM_RATIO )  - Offset.y)   );
		}
			
		tmp = tmp->GetNext();
	}

	if( m_characterController )
	{
		m_characterController->draw( Offset );
	}
}



void Player::updateAnim(ccTime dt)
{
	if( m_animController )
    {
        m_animController->update(dt);
    }
}

void Player::update(ccTime dt)
{
	if( m_characterController )
	{
		m_characterController->update(dt);
	}
	updateAnim(dt);
}